package me.zhengjie.modules.website.service.impl;

import me.zhengjie.modules.website.domain.AccessLogs;
import me.zhengjie.modules.website.dto.MonthlyStatisticsDto;
import me.zhengjie.modules.website.repository.AccessLogsRepository;
import me.zhengjie.modules.website.repository.AccessLogsSpecifications;
import me.zhengjie.modules.website.service.AccessLogsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import me.zhengjie.modules.website.domain.PageResult;

import java.time.LocalDate;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
 * @author system
 * @since 2024-12-02 16:18:43
 */
@Service
public class AccessLogsServiceImpl implements AccessLogsService {

    @Autowired
    private AccessLogsRepository accessLogsRepository;

    @Override
    public PageResult<AccessLogs> findPage(AccessLogs accessLogs, Pageable pageable) {
        Page<AccessLogs> page = accessLogsRepository.findAll(AccessLogsSpecifications.queryList(accessLogs), pageable);
        PageResult<AccessLogs> result = new PageResult();
        result.setContent(page.getContent());
        result.setTotalElements(page.getTotalElements());
        return result;
    }

    @Override
    public List<AccessLogs> findList(AccessLogs accessLogs) {
        return accessLogsRepository.findAll(AccessLogsSpecifications.queryList(accessLogs));
    }

    @Override
    public AccessLogs findById(Long id) {
        return accessLogsRepository.findById(id).orElse(null);
    }

    @Override
    public AccessLogs insert(AccessLogs accessLogs) {
        return accessLogsRepository.save(accessLogs);
    }

    @Override
    public AccessLogs update(AccessLogs accessLogs) {
        return accessLogsRepository.saveAndFlush(accessLogs);
    }

    @Override
    public void delete(Long id) {
        accessLogsRepository.deleteById(id);
    }


    @Override
    public List<MonthlyStatisticsDto> getMonthlyStatistics(Integer year) {
        // 默认使用当前年份
        int queryYear = (year != null) ? year : LocalDate.now().getYear();

        // 分别查询 PV 和 UV 数据
        List<Object[]> pageViews = accessLogsRepository.countPageViewsByMonth(queryYear);
        List<Object[]> uniqueVisitors = accessLogsRepository.countUniqueVisitorsByMonth(queryYear);


        List<MonthlyStatisticsDto> statistics = IntStream.rangeClosed(1, 12)
                .mapToObj(month -> {
                    long pv = pageViews.stream()
                            .filter(row -> (int) row[0] == month)
                            .mapToLong(row -> (long) row[1])
                            .findFirst()
                            .orElse(0L);
                    long uv = uniqueVisitors.stream()
                            .filter(row -> (int) row[0] == month)
                            .mapToLong(row -> (long) row[1])
                            .findFirst()
                            .orElse(0L);

                    return new MonthlyStatisticsDto(month, pv, uv);
                })
                .collect(Collectors.toList());

        return statistics;
    }

    @Override
    public List<Object[]> getVisitStatsForYear(int year) {
        return accessLogsRepository.getVisitStatsByProvinceForYear(year);
    }
}